package blackstar.plugin.monitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.event.Event;
import blackstar.agent.event.EventDispatcherSupport;
import blackstar.agent.event.EventListener;
import blackstar.agent.jvm.JMXProxy;
import blackstar.agent.jvm.JMXProxyShutdownEvent;
import blackstar.agent.jvm.JMXProxyStartupEvent;
import blackstar.agent.schedule.ScheduleEvent;
import blackstar.agent.schedule.ScheduleTask;
import blackstar.agent.schedule.UnscheduleEvent;
import blackstar.plugin.monitor.debug.DebugMonitorFactory;

public class MonitorManager extends EventDispatcherSupport implements
		EventListener
{
	private final static Log LOGGER = LogFactory.getLog(MonitorManager.class);

	private MonitorFactory monitorFactory = new DebugMonitorFactory();
	private Map<String, List<String>> monitorJobNames = new HashMap<String, List<String>>();

	public Class[] events()
	{
		return new Class[]
		{ JMXProxyStartupEvent.class, JMXProxyShutdownEvent.class };
	}

	public void onEvent(Event event) throws Exception
	{
		if (event instanceof JMXProxyStartupEvent)
		{
			startup(((JMXProxyStartupEvent) event).getJMXProxy());
		} else if (event instanceof JMXProxyShutdownEvent)
		{
			shutdown(((JMXProxyShutdownEvent) event).getJMXProxy());
		}
	}

	private void shutdown(JMXProxy proxy)
	{
		List<String> nameList = monitorJobNames.get(proxy.getId());
		if (nameList != null)
		{
			for (String name : nameList)
			{
				dispatch(new UnscheduleEvent(name));
			}
			monitorJobNames.remove(proxy.getId());
		}
	}

	private void startup(JMXProxy proxy)
	{
		shutdown(proxy);

		List<MonitorInfo> monitorInfos = monitorFactory.create(proxy);

		List<String> nameList = new ArrayList<String>();
		for (final MonitorInfo monitorInfo : monitorInfos)
		{
			try
			{
				final Monitor monitor = monitorInfo.getMonitorTask();
				monitor.init(proxy);
				String jobName = "jvm" + proxy.getId() + "_"
						+ monitor.getName();
				//分布定时调度
				dispatch(new ScheduleEvent(jobName, monitorInfo
						.getCronExpression(), new ScheduleTask()
				{
					public void schedule()
					{
						monitor.onTimeout();
					}
				}));
				nameList.add(jobName);

			} catch (Throwable t)
			{
				LOGGER.error("Init MOnitor And Task Failed", t);
			}
		}

		monitorJobNames.put(proxy.getId(), nameList);
	}
}
